<?php
/**
 * Niushop商城系统 - 团队十年电商经验汇集巨献!
 * =========================================================
 * Copy right 2019-2029 山西牛酷信息科技有限公司, 保留所有权利。
 * ----------------------------------------------
 * 官方网址: https://www.niushop.com.cn
 * 这不是一个自由软件！您只能在不用于商业目的的前提下对程序代码进行修改和使用。
 * 任何企业和个人不允许对程序代码以任何形式任何目的再发布。
 * =========================================================
 */

namespace app\model\system;

use think\facade\Cache;
use app\model\BaseModel;

/**
 * 系统配置类
 */
class Pay extends BaseModel
{

	public $refund_pay_type = array (
		"offline_refund_pay" => "线下退款",
		"online_refund_pay" => "原路退款"
	);

	/********************************************************************支付**********************************************************/

	/**
	 * 支付
	 * @param unknown $pay_type
	 * @param unknown $out_trade_no
	 * @param unknown $app_type 支付端口场景
	 * @return Ambigous <>
	 */
	public function pay($pay_type, $out_trade_no, $app_type, $member_id)
	{

		if (REWRITE_MODULE) {
			$notify_url = addon_url("pay/pay/notify");//https://bbyp.kangsitiankeji.cn/pay/pay/notify.html
		} else {
			$notify_url = request()->domain() . '/pay.php';
		}
		$return_url = addon_url("pay/pay/payreturn", ['out_trade_no' => $out_trade_no, 'app_type' => $app_type]);

		$pay_info = $this->getPayInfo($out_trade_no);
		$data = $pay_info[ 'data' ];
		$data[ 'app_type' ] = $app_type;
		$data[ 'notify_url' ] = $notify_url;
		$data[ 'return_url' ] = $return_url;
		$data[ 'pay_type' ] = $pay_type;
		$data[ "member_id" ] = $member_id;
		$res = event('Pay', $data, true);
		return $res;
	}

	/**
	 * 创建支付流水号
	 */
	public function createOutTradeNo()
	{
		$cache = Cache::get("pay_out_trade_no" . time());
		if (empty($cache)) {
			Cache::set("niubfd" . time(), 1000);
			$cache = Cache::get("pay_out_trade_no" . time());
		} else {
			$cache = $cache + 1;
			Cache::set("pay_out_trade_no" . time(), $cache);
		}
		$no = time() . rand(1000, 9999) . $cache;
		return $no;
	}

	/**
	 * 添加支付信息
	 * @param unknown $site_id //站点id  默认平台配置为0
	 * @param unknown $out_trade_no 交易流水号
	 * @param unknown $app_type 支付端口类型
	 * @param unknown $pay_type 支付方式，默认为空
	 * @param unknown $pay_body 支付主体
	 * @param unknown $pay_detail 支付细节
	 * @param unknown $pay_money 支付金额
	 * @param unknown $pay_no 支付账号
	 * @param unknown $notify_url 要求的异步回调网址，实际支付后会进行执行或者回调，可以是事件或者域名
	 * @param unknown $return_url 同步回调网址，知己支付后会进行同步回调
	 */
	public function addPay($site_id, $out_trade_no, $pay_type, $pay_body, $pay_detail, $pay_money, $pay_no, $notify_url, $return_url)
	{
		$data = array (
			'site_id' => $site_id,
			'out_trade_no' => $out_trade_no,
			'pay_body' => $pay_body,
			'pay_detail' => $pay_detail,
			'pay_money' => $pay_money,
			'pay_no' => $pay_no,
			"event" => $notify_url,
			'return_url' => $return_url,
			"pay_status" => 0,
			"create_time" => time(),
		);
		$result = model("pay")->add($data);
		if ($pay_money == 0) {
			$this->onlinePay($out_trade_no, $pay_type, '', '');
		}
		return $result;
	}
	public function connect(){
        $dbhost = '8.135.116.51';  // mysql服务器主机地址
        $dbuser = 'root';            // mysql用户名
        $dbpass = 'i4GsmFCkJdmYH4xN';          // mysql用户名密码
        $dbname = 'bby';
        $conn = mysqli_connect($dbhost, $dbuser, $dbpass,$dbname);
        if(! $conn )
        {
            die('Could not connect: ' . mysqli_error());
        }
        // echo '数据库连接成功！';
        // 设置编码，防止中文乱码
        mysqli_query($conn , "set names utf8");

        return $conn;
    }
	public function getAll($conn,$sql){
        #执行查询操作
        $result  = $conn->query($sql);
        if(empty($result)){
            return '';
        }
        #定义返回接收数据的数组
        $data = array();
        #判断是否有数据
        if($result->num_rows){
            #循环把数据插入返回的数组中
            while($row = $result->fetch_assoc()){
                $data[] = $row;
            }
        }
        mysqli_free_result($result);
        #返回
        return $data;
    }

	/**
	 * 在线支付
	 * @param $out_trade_no
	 * @param $pay_type
	 * @param $trade_no
	 * @param $pay_addon
	 * @return array
	 * @throws \Exception
	 */
	public function onlinePay($out_trade_no, $pay_type, $trade_no, $pay_addon)
	{

		$pay_info_result = $this->getPayInfo($out_trade_no);
		$pay_info = $pay_info_result[ "data" ];
		//支付状态 (未支付  未取消)
		if ($pay_info[ "pay_status" ] == 0) {
			$data = array (
				"trade_no" => $trade_no,
				"pay_type" => $pay_type,
				"pay_addon" => $pay_addon,
				"pay_time" => time(),
				"pay_status" => 2
			);
			$res = model("pay")->update($data, [ [ 'out_trade_no', '=', $out_trade_no ] ]);
			if ($res === false) {
				return error('', 'UNKNOW_ERROR');
			} else {
				//成功则直接给应用异步回调地址发送
				$return_data = array (
					'out_trade_no' => $out_trade_no,
					'trade_no' => $trade_no,
					'pay_type' => $pay_type
				);

				//根据事件成功后执行
				if (strpos($pay_info[ "event" ], 'http://') !== 0 || strpos($pay_info[ "event" ], 'https://') !== 0) {
					event($pay_info[ "event" ], $return_data);
				} else {
					http($pay_info[ "event" ], 1);

				}
				return $this->success($return_data);
			}
		} else {
			return $this->success('', "当前单据已支付");
		}

	}


	/**
	 * 删除并关闭支付
	 * @param $out_trade_no
	 */
	public function deletePay($out_trade_no)
	{
		$pay_info_result = $this->getPayInfo($out_trade_no);
		$pay_info = $pay_info_result[ "data" ];
		if (!empty($pay_info)) {
			//支付状态 (未支付  未取消)
			if ($pay_info[ "pay_status" ] == 0) {
				if (!empty($pay_info[ "pay_type" ])) {
					$close_result = event("payClose", $pay_info, true);
					if ($close_result[ "code" ] < 0) {
						return $close_result;
					}
				}
				$res = model("pay")->delete([ [ 'out_trade_no', '=', $out_trade_no ] ]);
				if ($res === false) {
					return $this->error('', 'UNKNOW_ERROR');
				} else {
					return $this->success($res);
				}
			} else {
				return $this->error([], "当前支付已完成");
			}
		} else {
			return $this->success();
		}
	}

	/**
	 * 重新生成新的pay支付记录
	 * @param $out_trade_no  原交易流水号
	 * @param $pay_money
	 */
	public function rewritePay($out_trade_no, $pay_money)
	{
		$pay_info_result = $this->getPayInfo($out_trade_no);
		$pay_info = $pay_info_result[ "data" ];
		//支付状态 (未支付  未取消)
		if ($pay_info[ "pay_status" ] == 0) {
			if (!empty($pay_info[ "pay_type" ])) {
				$close_result = event("payClose", $pay_info, true);
				if ($close_result[ "code" ] < 0) {
					return $close_result;
				}
			}
			$new_out_trade_no = $this->createOutTradeNo();
			$data = array (
				"out_trade_no" => $new_out_trade_no,
				"pay_money" => $pay_money
			);
			$res = model("pay")->update($data, [ [ 'out_trade_no', '=', $out_trade_no ] ]);
			if ($res === false) {
				return $this->error('', 'UNKNOW_ERROR');
			} else {

				return $this->success($new_out_trade_no);
			}
		} else {
			return $this->error([], "当前支付已完成");
		}
	}

	/**
	 * 支付绑定商户信息
	 * @param $condition
	 * @param $data
	 */
	public function bindMchPay($out_trade_no, $json_data)
	{
		$data = array (
			"mch_info" => json_encode($json_data, JSON_UNESCAPED_UNICODE)
		);
		$condition = array (
			[ "out_trade_no", "=", $out_trade_no ]
		);
		$res = model("pay")->update($data, $condition);
		return $res;
	}

	/**
	 * 获取支付方式
	 * @param unknown $params "pay_scene" => ["wap", "wechat", "app", "pc", "wechat_applet"]
	 */
	public function getPayType($params = [])
	{
		$res = event('PayType', $params);
		return $this->success($res);
	}

	/**
	 * 获取支付信息详情
	 * @param string $out_trade_no
	 */
	public function getPayInfo($out_trade_no)
	{
		$get_pay_list = model('pay')->getInfo([ [ 'out_trade_no', '=', $out_trade_no ] ]);
		return $this->success($get_pay_list);
	}

	/**
	 * 支付记录
	 * @param array $condition
	 * @param number $page
	 * @param string $page_size
	 * @param string $order
	 * @param string $field
	 * @return multitype:string mixed
	 */
	public function getPayPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*')
	{
		$list = model('pay')->pageList($condition, $field, $order, $page, $page_size);
		return $this->success($list);
	}

	/**
	 * 支付统计
	 * @param unknown $site_id
	 */
	public function getPayStatistics($condition)
	{
		$statistics_array = array (
			'count' => model('pay')->getCount($condition),
			'sum_money' => model('pay')->getSum($condition, 'pay_money')
		);
		return $statistics_array;
	}

	/****************************************************************退款**************************************************************/

	/**
	 * 创建退款流水号
	 */
	public function createRefundNo()
	{
		$cache = Cache::get("pay_refund_out_trade_no" . time());
		if (empty($cache)) {
			Cache::set("niutk" . time(), 1000);
			$cache = Cache::get("pay_refund_out_trade_no" . time());
		} else {
			$cache = $cache + 1;
			Cache::set("pay_refund_out_trade_no" . time(), $cache);
		}
		$no = date('Ymdhis', time()) . rand(1000, 9999) . $cache;
		return $no;
	}

	/**
	 * 原路退款
	 * @param $refund_no
	 * @param $refund_fee
	 * @param $out_trade_no
	 * @param $refund_desc
	 * @param $total_fee  实际支付金额
	 * @param $refund_type  退款方式 1 原路退款  2 线下支付
	 */
	public function refund($refund_no, $refund_fee, $out_trade_no, $refund_desc, $total_fee, $site_id, $refund_type)
	{


		//是否是原理退款方式退款
		if ($refund_type == 1) {
			$pay_info_result = $this->getPayInfo($out_trade_no);
			$pay_info = $pay_info_result[ "data" ];
			if (empty($pay_info))
				return $this->error('', "付款记录不存在!");

			$data = array (
				"refund_no" => $refund_no,
				"refund_fee" => $refund_fee,
				"refund_desc" => $refund_desc,
				"pay_info" => $pay_info,
				"total_fee" => $total_fee
			);
			//退款金额许大于0
			if ($refund_fee > 0 && !in_array($pay_info[ "pay_type" ], [ "OFFLINE_PAY", "BALANCE", "ONLINE_PAY" ])) {
				$result = event("PayRefund", $data, true);
				if (empty($result))
					return $this->error('', "找不到可用的退款方式!");

				if ($result[ "code" ] < 0)
					return $result;
			}


		}
		$refund_data = array (
			"refund_no" => $refund_no,
			"refund_fee" => $refund_fee,
			"total_money" => $total_fee,
			"refund_type" => $refund_type,
			"site_id" => $site_id,
			"out_trade_no" => $out_trade_no,
		);
		$this->addRefundPay($refund_data);
		return $this->success();

	}

	/**
	 * 添加退款记录
	 * @param unknown $data
	 */
	public function addRefundPay($data)
	{
		$data[ "create_time" ] = time();
		$data[ "refund_detail" ] = "支付交易号:" . $data[ 'out_trade_no' ] . "，退款金额:" . $data[ "refund_fee" ] . "元";
		$res = model("pay_refund")->add($data);
		if ($res == false) {
			return $this->error($res);
		}
		return $this->success($res);
	}

	/**
	 * 获取支付状态
	 * @param unknown $out_trade_no
	 * @return multitype:
	 */
	public function getPayStatus($out_trade_no)
	{
		$info = model('pay')->getInfo([ [ 'out_trade_no', '=', $out_trade_no ] ], 'pay_status');
		if (empty($info)) return $this->error();
		return $this->success($info);
	}

	/**
	 * 查询转账方式
	 * @return array
	 */
	public function getTransferType()
	{
		$temp_array = event("TransferType", []);

		if (!empty($temp_array)) {
			$temp_array = array_reverse($temp_array);
			foreach ($temp_array as $k => $v) {
				$data[ $v[ "type" ] ] = $v[ "type_name" ];
			}
		}
		$data[ 'bank' ] = "银行卡";
		return $data;
	}

}